using Google.Protobuf;

namespace muduoDotNet
{
    /// <summary>
    /// 默认的Protobuf消息处理器
    /// 提供基础的消息类型识别和分发功能
    /// </summary>
    public class ProtobufMessageHandler : IProtocolMessageHandler
    {
        private readonly Dictionary<string, Type> _messageTypes;
        private readonly Dictionary<Type, object> _callbacks;

        public ProtobufMessageHandler()
        {
            _messageTypes = new Dictionary<string, Type>();
            _callbacks = new Dictionary<Type, object>();
            
            // 注册内置消息类型
            RegisterMessageType<muduoDotNet.Messages.EchoRequest>();
            RegisterMessageType<muduoDotNet.Messages.EchoResponse>();
            RegisterMessageType<muduoDotNet.Messages.Heartbeat>();
            RegisterMessageType<muduoDotNet.Messages.StatusMessage>();
            RegisterMessageType<muduoDotNet.Messages.DataPacket>();
            RegisterMessageType<muduoDotNet.Messages.ConnectionInfo>();
            RegisterMessageType<muduoDotNet.Messages.DisconnectRequest>();
        }

        /// <summary>
        /// 注册消息类型
        /// </summary>
        /// <typeparam name="T">消息类型</typeparam>
        public void RegisterMessageType<T>() where T : class, IMessage<T>, new()
        {
            var type = typeof(T);
            var typeName = type.Name;
            _messageTypes[typeName] = type;
            Logger.Debug($"Registered protobuf message type: {typeName}");
        }

        /// <summary>
        /// 设置消息处理回调
        /// </summary>
        /// <typeparam name="T">消息类型</typeparam>
        /// <param name="callback">回调函数</param>
        public void SetMessageCallback<T>(ProtocolMessageCallback<T> callback) where T : class, IMessage
        {
            _callbacks[typeof(T)] = callback;
        }

        /// <summary>
        /// 移除消息处理回调
        /// </summary>
        /// <typeparam name="T">消息类型</typeparam>
        public void RemoveMessageCallback<T>() where T : class, IMessage
        {
            _callbacks.Remove(typeof(T));
        }

        /// <summary>
        /// 处理接收到的协议消息
        /// </summary>
        /// <param name="connection">TCP连接</param>
        /// <param name="message">消息对象</param>
        public void HandleMessage(TcpConnection connection, IMessage message)
        {
            var messageType = message.GetType();
            
            if (_callbacks.TryGetValue(messageType, out var callbackObj))
            {
                try
                {
                    // 使用反射调用对应的回调
                    var callbackType = typeof(ProtocolMessageCallback<>).MakeGenericType(messageType);
                    var callback = callbackObj as Delegate;
                    callback?.DynamicInvoke(connection, message);
                    
                    Logger.Debug($"Handled message: {messageType.Name}");
                }
                catch (Exception ex)
                {
                    Logger.Error($"Error handling message {messageType.Name}", ex);
                }
            }
            else
            {
                Logger.Warning($"No callback registered for message type: {messageType.Name}");
            }
        }

        /// <summary>
        /// 尝试从类型名称解析消息类型
        /// </summary>
        /// <param name="typeName">类型名称</param>
        /// <returns>消息类型，如果找不到返回null</returns>
        public Type? GetMessageType(string typeName)
        {
            _messageTypes.TryGetValue(typeName, out var type);
            return type;
        }

        /// <summary>
        /// 获取所有注册的消息类型
        /// </summary>
        /// <returns>消息类型列表</returns>
        public IEnumerable<Type> GetRegisteredMessageTypes()
        {
            return _messageTypes.Values;
        }
    }
}